package com.netty.esc.config.websocket;

import com.alibaba.fastjson.JSON;
import com.netty.esc.common.global.UserCache;
import com.netty.esc.entity.model.BaseDTO;
import com.netty.esc.service.active.UserActicveAction;
import com.netty.esc.service.isolate.UserBroadcast;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelId;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @Author: Etan96
 * @CreateDate: 2022/8/29 22:29
 * @Description:
 */
@Slf4j
@Component
public class WebSocketManager {

    @Resource
    UserBroadcast userBroadcast;
    @Resource
    private UserActicveAction userActicveAction;

    /**
     * socket推送文字消息
     * @param channel socket通道
     * @param textWebSocketFrame frame
     */
    public static void sendTextMessage(Channel channel, TextWebSocketFrame textWebSocketFrame){
        try {
            channel.writeAndFlush(textWebSocketFrame);
        }catch (Throwable throwable){
            log.error("socket推送消息出现异常。", throwable);
        }
    }

    public static void sendTextMessage(Channel channel, BaseDTO dto){
        try {
            sendTextMessage(channel, new TextWebSocketFrame(JSON.toJSONString(dto)));
        }catch (Throwable throwable){
            log.error("socket推送消息出现异常。", throwable);
        }
    }

    public static void sendTextMessage(ChannelHandlerContext context, BaseDTO dto){
        try {
            sendTextMessage(context.channel(), new TextWebSocketFrame(JSON.toJSONString(dto)));
        }catch (Throwable throwable){
            log.error("socket推送消息出现异常。", throwable);
        }
    }

    public static void sendTextMessage(Long userId, BaseDTO dto){
        try {
            ChannelId channelId = ChannelGroups.robotToChannel.get(userId);
            if (channelId != null){
                Channel channel = ChannelGroups.channelsApp.find(channelId);
                if (channel != null){
                    WebSocketManager.sendTextMessage(channel, new TextWebSocketFrame(JSON.toJSONString(dto)));
                    return;
                }
            }
            log.info("当前用户不在线：" + userId);
        }catch (Throwable throwable){
            log.error("socket推送消息出现异常。", throwable);
        }
    }


    public void ctxClose(ChannelHandlerContext context){
        context.disconnect();
        ctxClose(context.channel());
        context.close();
    }

    /**
     * 链接断开后，释放资源
     * @param channel channel
     */
    public void ctxClose(Channel channel){
        //获取ChannelId
        ChannelId channelId = channel.id();
        //通知好友已下线
        userActicveAction.userOffLine(ChannelGroups.channelToRobot.get(channel.id()));
        //根据ChannelId获取userId
        Long userId = ChannelGroups.channelToRobot.get(channelId);
        if (userId==null){
            return;
        }
        //释放 channelToRobot
        ChannelGroups.channelToRobot.remove(channelId);
        //释放 robotToChannel
        ChannelGroups.robotToChannel.remove(userId);

        userBroadcast.userDownLoad(userId);
        //释放Channel
        ChannelGroups.channelsApp.remove(channel);
        UserCache.remove();
    }
}
